package com.youlai.boot.modules.game.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.youlai.boot.common.result.PageResult;
import com.youlai.boot.core.security.util.SecurityUtils;
import com.youlai.boot.modules.game.converter.GameLeaderboardConverter;
import com.youlai.boot.modules.game.enums.LeaderboardPeriodEnum;
import com.youlai.boot.modules.game.enums.PointsActionEnum;
import com.youlai.boot.modules.game.mapper.GamePointsHistoryMapper;
import com.youlai.boot.modules.game.mapper.GameRankChangeMapper;
import com.youlai.boot.modules.game.mapper.GameUserPointsMapper;
import com.youlai.boot.modules.game.model.entity.GamePointsHistory;
import com.youlai.boot.modules.game.model.entity.GameUserPoints;
import com.youlai.boot.modules.game.model.form.GamePointsForm;
import com.youlai.boot.modules.game.model.form.GameUserProfileForm;
import com.youlai.boot.modules.game.model.query.GameLeaderboardQuery;
import com.youlai.boot.modules.game.model.vo.GameLeaderboardVO;
import com.youlai.boot.modules.game.model.vo.GameUserInfo;
import com.youlai.boot.modules.game.service.GameLeaderboardService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * 游戏排行榜服务实现类
 *
 * @author 有来技术团队
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class GameLeaderboardServiceImpl extends ServiceImpl<GameUserPointsMapper, GameUserPoints> implements GameLeaderboardService {

    private final GamePointsHistoryMapper gamePointsHistoryMapper;
    private final GameRankChangeMapper gameRankChangeMapper;

    @Override
    public List<GameLeaderboardVO> getLeaderboard(GameLeaderboardQuery query) {
        // 使用默认时间段
        if (StrUtil.isBlank(query.getPeriod())) {
            query.setPeriod(LeaderboardPeriodEnum.ALL.getCode());
        }
        
        // 获取排行榜数据
        List<GameUserPoints> leaderboard = baseMapper.getLeaderboard(query.getPeriod(), query.getLimit());
        
        // 转换为VO列表
        List<GameLeaderboardVO> voList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(leaderboard)) {
            voList = GameLeaderboardConverter.INSTANCE.entityList2voList(leaderboard);
        }
        
        return voList;
    }

    @Override
    public GameLeaderboardVO getUserRank(String period) {
        // 使用默认时间段
        if (StrUtil.isBlank(period)) {
            period = LeaderboardPeriodEnum.ALL.getCode();
        }
        
        // 获取当前登录用户ID
        Long userId = SecurityUtils.getUserId();
        
        // 获取用户排名
        GameUserPoints userRank = baseMapper.getUserRank(userId, period);
        if (userRank == null) {
            return null;
        }
        
        // 转换为VO
        return GameLeaderboardConverter.INSTANCE.entity2vo(userRank);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean updatePoints(GamePointsForm formData) {
        // 获取用户旧排名
        GameUserPoints oldRank = baseMapper.getUserRank(formData.getUserId(), LeaderboardPeriodEnum.ALL.getCode());
        Integer rankBefore = oldRank != null ? oldRank.getRank() : null;
        
        // 更新用户积分
        int rows = baseMapper.updateUserPoints(formData.getUserId(), formData.getPoints());
        
        if (rows > 0) {
            // 记录积分历史
            GamePointsHistory history = new GamePointsHistory();
            history.setUserId(formData.getUserId());
            history.setPoints(formData.getPoints());
            history.setActionType(formData.getActionType());
            history.setDescription(formData.getDescription());
            gamePointsHistoryMapper.insert(history);
            
            // 获取用户新排名
            GameUserPoints newRank = baseMapper.getUserRank(formData.getUserId(), LeaderboardPeriodEnum.ALL.getCode());
            Integer rankAfter = newRank != null ? newRank.getRank() : null;
            
            // 记录排名变化
            if (rankBefore != null && rankAfter != null) {
                recordRankChange(formData.getUserId(), LeaderboardPeriodEnum.ALL.getCode(), rankBefore, rankAfter);
                
                // 根据操作类型记录不同时间段的排名变化
                String actionType = formData.getActionType();
                PointsActionEnum actionEnum = PointsActionEnum.getByCode(actionType);
                if (actionEnum != null) {
                    // 日榜记录
                    if (actionEnum == PointsActionEnum.DAILY_LOGIN || 
                        actionEnum == PointsActionEnum.DAILY_CHECK_IN) {
                        GameUserPoints dailyRankBefore = baseMapper.getUserRank(formData.getUserId(), LeaderboardPeriodEnum.DAILY.getCode());
                        GameUserPoints dailyRankAfter = baseMapper.getUserRank(formData.getUserId(), LeaderboardPeriodEnum.DAILY.getCode());
                        if (dailyRankBefore != null && dailyRankAfter != null) {
                            recordRankChange(formData.getUserId(), LeaderboardPeriodEnum.DAILY.getCode(), 
                                    dailyRankBefore.getRank(), dailyRankAfter.getRank());
                        }
                    }
                    
                    // 周榜记录
                    if (actionEnum == PointsActionEnum.GAME_COMPLETE || 
                        actionEnum == PointsActionEnum.TASK_COMPLETE) {
                        GameUserPoints weeklyRankBefore = baseMapper.getUserRank(formData.getUserId(), LeaderboardPeriodEnum.WEEKLY.getCode());
                        GameUserPoints weeklyRankAfter = baseMapper.getUserRank(formData.getUserId(), LeaderboardPeriodEnum.WEEKLY.getCode());
                        if (weeklyRankBefore != null && weeklyRankAfter != null) {
                            recordRankChange(formData.getUserId(), LeaderboardPeriodEnum.WEEKLY.getCode(), 
                                    weeklyRankBefore.getRank(), weeklyRankAfter.getRank());
                        }
                    }
                    
                    // 月榜记录
                    if (actionEnum == PointsActionEnum.ACHIEVEMENT_UNLOCK || 
                        actionEnum == PointsActionEnum.INVITE_FRIEND ||
                        actionEnum == PointsActionEnum.GAME_PURCHASE) {
                        GameUserPoints monthlyRankBefore = baseMapper.getUserRank(formData.getUserId(), LeaderboardPeriodEnum.MONTHLY.getCode());
                        GameUserPoints monthlyRankAfter = baseMapper.getUserRank(formData.getUserId(), LeaderboardPeriodEnum.MONTHLY.getCode());
                        if (monthlyRankBefore != null && monthlyRankAfter != null) {
                            recordRankChange(formData.getUserId(), LeaderboardPeriodEnum.MONTHLY.getCode(), 
                                    monthlyRankBefore.getRank(), monthlyRankAfter.getRank());
                        }
                    }
                }
            }
        }
        
        return rows > 0;
    }

    @Override
    public PageResult<GamePointsHistory> getPointsHistory(Integer pageNum, Integer pageSize) {
        // 获取当前登录用户ID
        Long userId = SecurityUtils.getUserId();
        
        // 构建分页对象
        Page<GamePointsHistory> page = new Page<>(pageNum, pageSize);
        
        // 查询分页数据
        Page<GamePointsHistory> pageResult = gamePointsHistoryMapper.getUserPointsHistory(page, userId);
        
        return PageResult.success(pageResult.getTotal(), pageResult.getRecords());
    }

    @Override
    public boolean recordRankChange(Long userId, String period, Integer rankBefore, Integer rankAfter) {
        // 记录排名变化
        int rows = gameRankChangeMapper.recordRankChange(userId, period, rankBefore, rankAfter, LocalDate.now());
        
        return rows > 0;
    }
    
    /**
     * 更新用户资料
     *
     * @param formData 用户资料表单
     * @return 是否成功
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean updateUserProfile(GameUserProfileForm formData) {
        // 获取用户ID
        Long userId = formData.getUserId();
        
        // 查询用户信息
        GameUserPoints userPoints = this.lambdaQuery()
                .eq(GameUserPoints::getUserId, userId)
                .one();
        
        if (userPoints == null) {
            // 如果用户不存在，创建新用户记录
            userPoints = new GameUserPoints();
            userPoints.setUserId(userId);
            userPoints.setPoints(0);
            userPoints.setLevel(1);
        }
        
        // 更新用户信息
        userPoints.setUsername(formData.getUsername());
        
        // 头像可能为空，有值才更新
        if (StrUtil.isNotBlank(formData.getAvatar())) {
            userPoints.setAvatar(formData.getAvatar());
        }
        
        // 保存或更新用户信息
        return this.saveOrUpdate(userPoints);
    }
    
    @Override
    public Page<GameUserInfo> getUserPointsPage(Integer pageNum, Integer pageSize, String username) {
        // 构建分页对象
        Page<GameUserInfo> page = new Page<>(pageNum, pageSize);
        
        try {
            // 查询用户积分数据
            Page<GameUserPoints> userPointsPage = null;
            if (StrUtil.isNotBlank(username)) {
                userPointsPage = this.lambdaQuery()
                        .like(GameUserPoints::getUsername, username)
                        .page(new Page<>(pageNum, pageSize));
            } else {
                userPointsPage = this.page(new Page<>(pageNum, pageSize));
            }
            
            // 设置总记录数
            if (userPointsPage != null) {
                page.setTotal(userPointsPage.getTotal());
                
                // 转换为GameUserInfo列表
                List<GameUserInfo> records = new ArrayList<>();
                for (GameUserPoints userPoints : userPointsPage.getRecords()) {
                    GameUserInfo userInfo = convertToGameUserInfo(userPoints);
                    records.add(userInfo);
                }
                
                page.setRecords(records);
            }
        } catch (Exception e) {
            log.error("获取用户积分分页列表失败", e);
        }
        
        return page;
    }
    
    @Override
    public GameUserInfo getUserPoints(Long userId) {
        if (userId == null) {
            // 如果未指定用户ID，使用当前登录用户ID
            userId = SecurityUtils.getUserId();
        }
        
        try {
            // 查询用户积分信息
            GameUserPoints userPoints = this.lambdaQuery()
                    .eq(GameUserPoints::getUserId, userId)
                    .one();
            
            if (userPoints != null) {
                return convertToGameUserInfo(userPoints);
            }
        } catch (Exception e) {
            log.error("获取用户积分详情失败", e);
        }
        
        return null;
    }
    
    /**
     * 将GameUserPoints转换为GameUserInfo
     *
     * @param userPoints 用户积分实体
     * @return 游戏用户信息VO
     */
    private GameUserInfo convertToGameUserInfo(GameUserPoints userPoints) {
        if (userPoints == null) {
            return null;
        }
        
        GameUserInfo userInfo = new GameUserInfo();
        userInfo.setId(userPoints.getUserId());
        userInfo.setUsername(userPoints.getUsername());
        userInfo.setAvatar(userPoints.getAvatar());
        userInfo.setLevel(userPoints.getLevel());
        userInfo.setPoints(userPoints.getPoints());
        
        // 随机生成排名趋势（模拟数据）
        Random random = new Random();
        userInfo.setTrend(random.nextInt(5) - 2); // 生成-2到2之间的随机数
        
        userInfo.setCreateTime(userPoints.getCreateTime());
        userInfo.setUpdateTime(userPoints.getUpdateTime());
        
        return userInfo;
    }
} 